--- /dev/null
+/*
+
+ Support for Digital Mapping TrackLogs (.trl) files,
+
+ Copyright (C) 2006 Olaf Klein, o.b.klein@t-online.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "jeeps/gpsmath.h"
+#include "xmlgeneric.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MYNAME "dmtlog"
+
+#define DEFLATE_BUFF_SIZE 16384
+
+static gbfile *fin, *fout;
+
+static char *xmlbin;
+static waypoint *xmlwpt;
+static route_head *xmltrk;
+static char *xmlgrid;
+static int xmldatum, datum_WGS84, datum_OSGB36;
+static double xmlEasting, xmlNorthing;
+static double xmlLatitude, xmlLongitude;
+static double xmlAltitude;
+
+#if !ZLIB_INHIBITED
+static int xmlbinsize;
+#endif
+
+static char header_written;
+static char *opt_index;
+static int track_index, this_index;
+
+static
+arglist_t dmtlog_args[] = {
+ { "index", &opt_index,
+ "Index of track (if more the one in source)", "1", ARGTYPE_INT, "1", NULL },
+ ARG_TERMINATOR
+};
+
+
+#if !ZLIB_INHIBITED
+static xg_callback tlog3a_xgcb_version, tlog3a_xgcb_length, tlog3a_xgcb_data;
+
+static xg_tag_mapping tlog3a_xgcb_map[] = {
+ { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" },
+ { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" },
+ { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" },
+ { NULL, 0, NULL}
+};
+#endif
+
+static xg_callback tlog3b_xgcb_tfna, tlog3b_xgcb_tfdes;
+static xg_callback tlog3b_xgcb_wptst, tlog3b_xgcb_tptst;
+static xg_callback tlog3b_xgcb_tpten, tlog3b_xgcb_wpten;
+static xg_callback tlog3b_xgcb_wptid, tlog3b_xgcb_wptdt;
+static xg_callback tlog3b_xgcb_wptgr, tlog3b_xgcb_wptea;
+static xg_callback tlog3b_xgcb_wptno, tlog3b_xgcb_wptal;
+static xg_callback tlog3b_xgcb_tptdt;
+
+static xg_tag_mapping tlog3b_xgcb_map[] = {
+ { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" },
+ { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" },
+ { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" },
+ { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" },
+ { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" },
+ { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" },
+ { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" },
+ { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" },
+ { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" },
+ { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" },
+ { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" },
+ { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" },
+ { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" },
+ { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" },
+ { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" },
+ { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" },
+ { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" },
+ { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" },
+ { NULL, 0, NULL}
+};
+
+/* helpers */
+
+static void
+convert_datum(waypoint *wpt, int datum)
+{
+ if (datum != datum_WGS84) {
+ double lat = wpt->latitude;
+ double lon = wpt->longitude;
+ double alt = wpt->altitude;
+ GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt,
+ &wpt->latitude, &wpt->longitude, &wpt->altitude,
+ datum);
+ }
+}
+
+
+static void
+finalize_pt(waypoint *wpt)
+{
+ if (strcmp(xmlgrid, "BNG") == 0) {
+ GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing,
+ &wpt->latitude, &wpt->longitude);
+ xmldatum = datum_OSGB36;
+ }
+ else {
+ wpt->latitude = xmlLatitude;
+ wpt->longitude = xmlLongitude;
+ }
+ wpt->altitude = xmlAltitude;
+ convert_datum(wpt, xmldatum);
+}
+
+/* xml-reader callbacks */
+
+#if !ZLIB_INHIBITED
+static void
+tlog3a_xgcb_version(const char *args, const char **unused)
+{
+ if (strcmp(args, "1") != 0)
+ fatal(MYNAME ": Unsupported file version '%s'!\n", args);
+}
+
+static void
+tlog3a_xgcb_length(const char *args, const char **unused)
+{
+}
+
+static void
+tlog3a_xgcb_data(const char *args, const char **unused)
+{
+ int len;
+ char *bin;
+ char *cin, *cout;
+ char cl, ch;
+
+ len = strlen(args);
+ bin = xmalloc((len >> 1) + 1);
+
+ cin = (char *)args;
+ cout = bin;
+
+ cl = 0x10;
+ while (*cin) {
+ char c = *cin++;
+
+ if (c == '\0') break;
+ else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10;
+ else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10;
+ else if ((c >= '0') && (c <= '9')) c -= '0';
+ else continue;
+
+ if (cl == 0x10) cl = c;
+ else {
+ ch = (cl << 4) | c;
+ *cout++ = ch;
+ cl = 0x10;
+ }
+ }
+ xmlbin = bin;
+ xmlbinsize = (cout - bin);
+}
+#endif
+
+
+static void
+tlog3b_xgcb_tfna(const char *args, const char **unused)
+{
+ if (xmltrk == NULL) {
+ xmltrk = route_head_alloc();
+ track_add_head(xmltrk);
+ }
+ xmltrk->rte_name = strdup(args);
+}
+
+
+static void
+tlog3b_xgcb_tfdes(const char *args, const char **unused)
+{
+ if (xmltrk == NULL) {
+ xmltrk = route_head_alloc();
+ track_add_head(xmltrk);
+ }
+ xmltrk->rte_desc = strdup(args);
+}
+
+
+static void
+tlog3b_xgcb_wptst(const char *args, const char **unused)
+{
+ xmlwpt = waypt_new();
+ xmldatum = datum_WGS84;
+}
+
+
+static void
+tlog3b_xgcb_tptst(const char *args, const char **unused)
+{
+ xmlwpt = waypt_new();
+ xmldatum = datum_WGS84;
+}
+
+
+static void
+tlog3b_xgcb_tpten(const char *args, const char **unused)
+{
+ finalize_pt(xmlwpt);
+
+ if (xmltrk == NULL) {
+ xmltrk = route_head_alloc();
+ track_add_head(xmltrk);
+ }
+ track_add_wpt(xmltrk, xmlwpt);
+ xmlwpt = NULL;
+}
+
+
+static void
+tlog3b_xgcb_wptid(const char *args, const char **unused)
+{
+ if (*args)
+ xmlwpt->shortname = xstrdup(args);
+}
+
+
+static void
+tlog3b_xgcb_wptdt(const char *args, const char **unused)
+{
+ xmldatum = GPS_Lookup_Datum_Index(args);
+}
+
+
+static void
+tlog3b_xgcb_wptgr(const char *args, const char **unused)
+{
+ if (xmlgrid != NULL) {
+ if (strcmp(xmlgrid, args) == 0) return;
+ xfree(xmlgrid);
+ }
+ xmlgrid = xstrdup(args);
+}
+
+
+static void
+tlog3b_xgcb_wptno(const char *args, const char **unused)
+{
+ xmlNorthing = atof(args);
+}
+
+
+static void
+tlog3b_xgcb_wptea(const char *args, const char **unused)
+{
+ xmlEasting = atof(args);
+}
+
+
+static void
+tlog3b_xgcb_wptal(const char *args, const char **unused)
+{
+ xmlAltitude = atof(args);
+}
+
+
+static void
+tlog3b_xgcb_tptdt(const char *args, const char **unused)
+{
+ xmldatum = GPS_Lookup_Datum_Index(args);
+}
+
+
+static void
+tlog3b_xgcb_wpten(const char *args, const char **unused)
+{
+ finalize_pt(xmlwpt);
+ waypt_add(xmlwpt);
+ xmlwpt = NULL;
+}
+
+
+static int
+read_datum(gbfile *f)
+{
+ int res;
+ char *d, *g;
+
+ d = gbfgetpstr(f);
+ g = gbfgetpstr(f);
+
+ res = GPS_Lookup_Datum_Index(d);
+
+ if (*g && (strcmp(d, g) != 0)) {
+ fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n",
+ d, g);
+ }
+ xfree(d);
+ xfree(g);
+
+ return res;
+}
+
+
+static void
+read_CTrackFile(const int version)
+{
+ char buf[128];
+ gbuint32 ver;
+ gbint32 tcount, wcount;
+ gbint16 u1;
+ gbint32 ux;
+ route_head *track;
+ int i;
+ int datum;
+
+ u1 = gbfgetint16(fin);
+
+ gbfread(buf, 1, 10, fin);
+ if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0))
+ fatal(MYNAME ": Unknown or invalid track file.\n");
+
+ if (version == 8) {
+ for (i = 1; i <= 9; i++)
+ gbfread(buf, 1, 4, fin);
+ }
+ ver = gbfgetint32(fin);
+ if (ver != version)
+ fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver);
+
+ ux = gbfgetint32(fin); // Unknown 2
+ ux = gbfgetint32(fin); // Unknown 3
+ ux = gbfgetint32(fin); // Unknown 4
+
+ track = route_head_alloc();
+ track_add_head(track);
+
+ /* S1 .. S9: comments, hints, jokes, aso */
+ for (i = 0; i < 9; i++) {
+ int c = gbfgetc(fin);
+ gbfseek(fin, c, SEEK_CUR);
+ }
+
+ tcount = gbfgetint32(fin);
+ if (tcount > 0) {
+ datum = read_datum(fin);
+ if (version == 8) {
+ int len;
+
+ gbfread(buf, 1, 4, fin);
+ len = gbfgetint16(fin);
+ gbfseek(fin, len, SEEK_CUR);
+ }
+ }
+
+ while (tcount > 0)
+ {
+ waypoint *wpt;
+
+ tcount--;
+
+ if (version == 8)
+ datum = read_datum(fin);
+
+ wpt = waypt_new();
+
+ wpt->latitude = gbfgetdbl(fin);
+ wpt->longitude = gbfgetdbl(fin);
+ wpt->altitude = gbfgetdbl(fin);
+
+ convert_datum(wpt, datum);
+
+ track_add_wpt(track, wpt);
+
+ if (version == 8)
+ gbfseek(fin, 34, SEEK_CUR);
+ }
+
+ wcount = gbfgetint32(fin);
+
+ if (wcount == 0) return;
+
+ if (version == 8) {
+ warning(MYNAME ": We don't yet support waypoints for this file version!\n");
+ return;
+ }
+
+ datum = read_datum(fin);
+
+ while (wcount > 0) {
+ waypoint *wpt;
+ gbint32 namect, i;
+
+ wcount--;
+
+ if (version == 8)
+ datum = read_datum(fin);
+
+ wpt = waypt_new();
+
+ wpt->latitude = gbfgetdbl(fin);
+ wpt->longitude = gbfgetdbl(fin);
+ wpt->altitude = gbfgetdbl(fin);
+
+ convert_datum(wpt, datum);
+
+ namect = gbfgetint32(fin);
+
+ // variants of shortname
+
+ for (i = 0; i < namect; i++) {
+ char *name = gbfgetpstr(fin);
+ if (name && *name) {
+ switch(i) {
+ case 0: wpt->description = xstrdup(name); break;
+ case 1: wpt->shortname = xstrdup(name); break;
+ }
+ }
+ xfree(name);
+ }
+ if (version == 8)
+ gbfseek(fin, 34, SEEK_CUR);
+
+ waypt_add(wpt);
+ }
+}
+
+
+#if !ZLIB_INHIBITED
+
+static int
+inflate_buff(const char *buff, const size_t size, char **out_buff)
+{
+ int res = Z_OK;
+ z_stream strm;
+ char out[DEFLATE_BUFF_SIZE];
+ char *cout = NULL;
+ gbuint32 bytes = 0;
+ gbuint32 have;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+
+ res = inflateInit(&strm);
+ if (res != Z_OK) {
+ return res;
+ }
+
+ strm.avail_in = size;
+ strm.next_in = (void *)buff;
+
+ do {
+ strm.avail_out = DEFLATE_BUFF_SIZE;
+ strm.next_out = (void *)out;
+ res = inflate(&strm, Z_NO_FLUSH);
+
+ switch (res) {
+ case Z_NEED_DICT:
+ res = Z_DATA_ERROR; /* and fall through */
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ (void)inflateEnd(&strm);
+ return res;
+ }
+ have = DEFLATE_BUFF_SIZE - strm.avail_out;
+ if (have > 0) {
+ cout = xrealloc(cout, bytes + have);
+ memcpy(cout+bytes, out, have);
+ bytes+=have;
+ }
+ } while (strm.avail_out == 0);
+
+ *out_buff = cout;
+ return res;
+}
+
+
+static void
+read_CXMLSafe(void)
+{
+ char *xmlstr = NULL;
+
+ xmlbin = NULL;
+ xmlbinsize = 0;
+
+ xml_init(fin->name, tlog3a_xgcb_map, NULL);
+ xml_read();
+ xml_deinit();
+
+ if (xmlbin != NULL) {
+ inflate_buff(xmlbin, xmlbinsize, &xmlstr);
+ xfree(xmlbin);
+
+ xml_init(NULL, tlog3b_xgcb_map, NULL);
+ xml_readstring(xmlstr);
+ xml_deinit();
+
+ xfree(xmlstr);
+ }
+}
+
+#endif
+
+static void
+read_XML(void)
+{
+ xml_init(fin->name, tlog3b_xgcb_map, NULL);
+ xml_read();
+ xml_deinit();
+
+ return;
+}
+
+/*******************************************************************************
+* %%% global callbacks called by gpsbabel main process %%% *
+*******************************************************************************/
+
+static void
+dmtlog_rd_init(const char *fname)
+{
+ fin = gbfopen_le(fname, "rb", MYNAME);
+
+ datum_OSGB36 = GPS_Lookup_Datum_Index("OSGB36");
+ datum_WGS84 = GPS_Lookup_Datum_Index("WGS84");
+
+ xmlbin = NULL;
+ xmltrk = NULL;
+ xmlwpt = NULL;
+ xmlgrid = NULL;
+}
+
+static void
+dmtlog_rd_deinit(void)
+{
+ gbfclose(fin);
+ if (xmlgrid != NULL) xfree(xmlgrid);
+}
+
+static void
+dmtlog_read(void)
+{
+ switch(gbfgetuint32(fin)) {
+
+ case 0x4FFFF:
+ read_CTrackFile(4);
+ break;
+
+ case 0x8FFFF:
+ read_CTrackFile(8);
+ break;
+
+ case 0x4d58433c:
+#if !ZLIB_INHIBITED
+ read_CXMLSafe();
+#else
+ fatal(MYNAME ": Zlib was not included in this build.\n");
+#endif
+ break;
+ case 0x7254433c:
+ read_XML();
+ break;
+
+ default:
+ fatal(MYNAME ": Unknown or unsupported file type.\n");
+ }
+}
+
+static void
+dmtlog_wr_init(const char *fname)
+{
+ fout = gbfopen_le(fname, "wb", MYNAME);
+}
+
+static void
+dmtlog_wr_deinit(void)
+{
+ gbfclose(fout);
+}
+
+static void
+write_header(const route_head *trk)
+{
+ int count, i;
+ char *cout;
+ const char ZERO = '\0';
+
+ header_written = 1;
+
+ count = 0;
+ if (trk != NULL) {
+ queue *curr, *prev;
+ QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++;
+ }
+ gbfputpstr(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout);
+
+ xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count());
+ gbfputpstr(cout, fout);
+ xfree(cout);
+
+ for (i = 3; i <= 8; i++) gbfputc(ZERO, fout);
+ gbfputpstr("GPSBabel", fout);
+ gbfputint32(count, fout);
+ if (count > 0) {
+ gbfputpstr("WGS84", fout);
+ gbfputpstr("WGS84", fout);
+ }
+}
+
+static void
+track_hdr_cb(const route_head *trk)
+{
+
+ this_index++;
+ if (this_index != track_index) return;
+ write_header(trk);
+}
+
+static void
+track_tlr_cb(const route_head *trk)
+{
+}
+
+static void
+track_wpt_cb(const waypoint *wpt)
+{
+ if (this_index != track_index) return;
+
+ gbfputdbl(wpt->latitude, fout);
+ gbfputdbl(wpt->longitude, fout);
+ gbfputdbl(wpt->altitude, fout);
+}
+
+static void
+wpt_cb(const waypoint *wpt)
+{
+ int names;
+
+ gbfputdbl(wpt->latitude, fout);
+ gbfputdbl(wpt->longitude, fout);
+ gbfputdbl(wpt->altitude, fout);
+
+ names = 1;
+ if (wpt->description && *wpt->description) names = 2;
+ gbfputint32(names, fout);
+ if (names > 1) gbfputpstr(wpt->description, fout);
+ gbfputpstr(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout);
+}
+
+static void
+dmtlog_write(void)
+{
+ track_index = atoi(opt_index);
+ /* ... validate index */
+
+ gbfputint32(0x4FFFF, fout);
+ gbfputuint16(0x0A, fout);
+ gbfputs("CTrackFile", fout);
+ gbfputint32(4, fout);
+ gbfputint32(1, fout);
+ gbfputint32(0x100001, fout);
+ gbfputuint32((const gbuint32)gpsbabel_now, fout);
+
+ header_written = 0;
+ this_index = 0;
+ track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb);
+ if (!header_written)
+ write_header(NULL);
+ gbfputint32(waypt_count(), fout);
+ if (waypt_count() > 0) {
+ gbfputpstr("WGS84", fout);
+ gbfputpstr("WGS84", fout);
+ waypt_disp_all(wpt_cb);
+ }
+}
+
+/**************************************************************************/
+
+ff_vecs_t dmtlog_vecs = {
+ ff_type_file,
+ {
+ ff_cap_read | ff_cap_write /* waypoints */,
+ ff_cap_read | ff_cap_write /* tracks */,
+ ff_cap_none /* routes */
+ },
+ dmtlog_rd_init,
+ dmtlog_wr_init,
+ dmtlog_rd_deinit,
+ dmtlog_wr_deinit,
+ dmtlog_read,
+ dmtlog_write,
+ NULL,
+ dmtlog_args,
+ CET_CHARSET_ASCII, 0
+
+};
+
+/**************************************************************************/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="30.045517000" minlon ="-91.610567000" maxlat="42.468655000" maxlon="-71.102973000" />
+<wpt lat="42.438878000" lon="-71.119277000">
+ <ele>44.586548</ele>
+ <name>5066</name>
+ <cmt>5066</cmt>
+ <desc>5066</desc>
+</wpt>
+<wpt lat="42.439227000" lon="-71.119689000">
+ <ele>57.607200</ele>
+ <name>5067</name>
+ <cmt>5067</cmt>
+ <desc>5067</desc>
+</wpt>
+<wpt lat="42.438917000" lon="-71.116146000">
+ <ele>44.826904</ele>
+ <name>5096</name>
+ <cmt>5096</cmt>
+ <desc>5096</desc>
+</wpt>
+<wpt lat="42.443904000" lon="-71.122044000">
+ <ele>50.594727</ele>
+ <name>5142</name>
+ <cmt>5142</cmt>
+ <desc>5142</desc>
+</wpt>
+<wpt lat="42.447298000" lon="-71.121447000">
+ <ele>127.711200</ele>
+ <name>5156</name>
+ <cmt>5156</cmt>
+ <desc>5156</desc>
+</wpt>
+<wpt lat="42.454873000" lon="-71.125094000">
+ <ele>96.926400</ele>
+ <name>5224</name>
+ <cmt>5224</cmt>
+ <desc>5224</desc>
+</wpt>
+<wpt lat="42.459079000" lon="-71.124988000">
+ <ele>82.600800</ele>
+ <name>5229</name>
+ <cmt>5229</cmt>
+ <desc>5229</desc>
+</wpt>
+<wpt lat="42.456979000" lon="-71.124474000">
+ <ele>82.905600</ele>
+ <name>5237</name>
+ <cmt>5237</cmt>
+ <desc>5237</desc>
+</wpt>
+<wpt lat="42.454401000" lon="-71.120990000">
+ <ele>66.696655</ele>
+ <name>5254</name>
+ <cmt>5254</cmt>
+ <desc>5254</desc>
+</wpt>
+<wpt lat="42.451442000" lon="-71.121746000">
+ <ele>74.627442</ele>
+ <name>5258</name>
+ <cmt>5258</cmt>
+ <desc>5258</desc>
+</wpt>
+<wpt lat="42.454404000" lon="-71.120660000">
+ <ele>65.254761</ele>
+ <name>5264</name>
+ <cmt>5264</cmt>
+ <desc>5264</desc>
+</wpt>
+<wpt lat="42.457761000" lon="-71.121045000">
+ <ele>77.419200</ele>
+ <name>526708</name>
+ <cmt>526708</cmt>
+ <desc>526708</desc>
+</wpt>
+<wpt lat="42.457089000" lon="-71.120313000">
+ <ele>74.676000</ele>
+ <name>526750</name>
+ <cmt>526750</cmt>
+ <desc>526750</desc>
+</wpt>
+<wpt lat="42.456592000" lon="-71.119676000">
+ <ele>78.713135</ele>
+ <name>527614</name>
+ <cmt>527614</cmt>
+ <desc>527614</desc>
+</wpt>
+<wpt lat="42.456252000" lon="-71.119356000">
+ <ele>78.713135</ele>
+ <name>527631</name>
+ <cmt>527631</cmt>
+ <desc>527631</desc>
+</wpt>
+<wpt lat="42.458148000" lon="-71.119135000">
+ <ele>68.275200</ele>
+ <name>5278</name>
+ <cmt>5278</cmt>
+ <desc>5278</desc>
+</wpt>
+<wpt lat="42.459377000" lon="-71.117693000">
+ <ele>64.008000</ele>
+ <name>5289</name>
+ <cmt>5289</cmt>
+ <desc>5289</desc>
+</wpt>
+<wpt lat="42.464183000" lon="-71.119828000">
+ <ele>52.997925</ele>
+ <name>5374FIRE</name>
+ <cmt>5374FIRE</cmt>
+ <desc>5374FIRE</desc>
+</wpt>
+<wpt lat="42.465650000" lon="-71.119399000">
+ <ele>56.388000</ele>
+ <name>5376</name>
+ <cmt>5376</cmt>
+ <desc>5376</desc>
+</wpt>
+<wpt lat="42.439018000" lon="-71.114456000">
+ <ele>56.388000</ele>
+ <name>6006</name>
+ <cmt>600698</cmt>
+ <desc>600698</desc>
+</wpt>
+<wpt lat="42.438594000" lon="-71.114803000">
+ <ele>46.028564</ele>
+ <name>6006BLUE</name>
+ <cmt>6006BLUE</cmt>
+ <desc>6006BLUE</desc>
+</wpt>
+<wpt lat="42.436757000" lon="-71.113223000">
+ <ele>37.616943</ele>
+ <name>6014MEADOW</name>
+ <cmt>6014MEADOW</cmt>
+ <desc>6014MEADOW</desc>
+</wpt>
+<wpt lat="42.441754000" lon="-71.113220000">
+ <ele>56.388000</ele>
+ <name>6029</name>
+ <cmt>6029</cmt>
+ <desc>6029</desc>
+</wpt>
+<wpt lat="42.436243000" lon="-71.109075000">
+ <ele>50.292000</ele>
+ <name>6053</name>
+ <cmt>6053</cmt>
+ <desc>6053</desc>
+</wpt>
+<wpt lat="42.439250000" lon="-71.107500000">
+ <ele>25.603200</ele>
+ <name>6066</name>
+ <cmt>6066</cmt>
+ <desc>6066</desc>
+</wpt>
+<wpt lat="42.439764000" lon="-71.107582000">
+ <ele>34.442400</ele>
+ <name>6067</name>
+ <cmt>6067</cmt>
+ <desc>6067</desc>
+</wpt>
+<wpt lat="42.434766000" lon="-71.105874000">
+ <ele>30.480000</ele>
+ <name>6071</name>
+ <cmt>6071</cmt>
+ <desc>6071</desc>
+</wpt>
+<wpt lat="42.433304000" lon="-71.106599000">
+ <ele>15.240000</ele>
+ <name>6073</name>
+ <cmt>6073</cmt>
+ <desc>6073</desc>
+</wpt>
+<wpt lat="42.437338000" lon="-71.104772000">
+ <ele>37.795200</ele>
+ <name>6084</name>
+ <cmt>6084</cmt>
+ <desc>6084</desc>
+</wpt>
+<wpt lat="42.442196000" lon="-71.110975000">
+ <ele>64.008000</ele>
+ <name>6130</name>
+ <cmt>6130</cmt>
+ <desc>6130</desc>
+</wpt>
+<wpt lat="42.442981000" lon="-71.111441000">
+ <ele>64.008000</ele>
+ <name>6131</name>
+ <cmt>6131</cmt>
+ <desc>6131</desc>
+</wpt>
+<wpt lat="42.444773000" lon="-71.108882000">
+ <ele>62.788800</ele>
+ <name>6153</name>
+ <cmt>6153</cmt>
+ <desc>6153</desc>
+</wpt>
+<wpt lat="42.443592000" lon="-71.106301000">
+ <ele>55.473600</ele>
+ <name>6171</name>
+ <cmt>6171</cmt>
+ <desc>6171</desc>
+</wpt>
+<wpt lat="42.447804000" lon="-71.106624000">
+ <ele>62.484000</ele>
+ <name>6176</name>
+ <cmt>6176</cmt>
+ <desc>6176</desc>
+</wpt>
+<wpt lat="42.448448000" lon="-71.106158000">
+ <ele>62.179200</ele>
+ <name>6177</name>
+ <cmt>6177</cmt>
+ <desc>6177</desc>
+</wpt>
+<wpt lat="42.453415000" lon="-71.106783000">
+ <ele>69.799200</ele>
+ <name>6272</name>
+ <cmt>6272</cmt>
+ <desc>6272</desc>
+</wpt>
+<wpt lat="42.453434000" lon="-71.107253000">
+ <ele>73.152000</ele>
+ <name>6272</name>
+ <cmt>6272</cmt>
+ <desc>6272</desc>
+</wpt>
+<wpt lat="42.458298000" lon="-71.106771000">
+ <ele>70.104000</ele>
+ <name>6278</name>
+ <cmt>6278</cmt>
+ <desc>6278</desc>
+</wpt>
+<wpt lat="42.451430000" lon="-71.105413000">
+ <ele>57.564209</ele>
+ <name>6280</name>
+ <cmt>6280</cmt>
+ <desc>6280</desc>
+</wpt>
+<wpt lat="42.453845000" lon="-71.105206000">
+ <ele>66.696655</ele>
+ <name>6283</name>
+ <cmt>6283</cmt>
+ <desc>6283</desc>
+</wpt>
+<wpt lat="42.459986000" lon="-71.106170000">
+ <ele>72.945191</ele>
+ <name>6289</name>
+ <cmt>6289</cmt>
+ <desc>6289</desc>
+</wpt>
+<wpt lat="42.457616000" lon="-71.105116000">
+ <ele>72.847200</ele>
+ <name>6297</name>
+ <cmt>6297</cmt>
+ <desc>6297</desc>
+</wpt>
+<wpt lat="42.467110000" lon="-71.113574000">
+ <ele>53.644800</ele>
+ <name>6328</name>
+ <cmt>6328</cmt>
+ <desc>6328</desc>
+</wpt>
+<wpt lat="42.464202000" lon="-71.109863000">
+ <ele>43.891200</ele>
+ <name>6354</name>
+ <cmt>6354</cmt>
+ <desc>6354</desc>
+</wpt>
+<wpt lat="42.466459000" lon="-71.110067000">
+ <ele>48.768000</ele>
+ <name>635722</name>
+ <cmt>635722</cmt>
+ <desc>635722</desc>
+</wpt>
+<wpt lat="42.466557000" lon="-71.109410000">
+ <ele>49.072800</ele>
+ <name>635783</name>
+ <cmt>635783</cmt>
+ <desc>635783</desc>
+</wpt>
+<wpt lat="42.463495000" lon="-71.107117000">
+ <ele>62.484000</ele>
+ <name>6373</name>
+ <cmt>6373</cmt>
+ <desc>6373</desc>
+</wpt>
+<wpt lat="42.401051000" lon="-71.110241000">
+ <ele>3.962400</ele>
+ <name>6634</name>
+ <cmt>6634</cmt>
+ <desc>6634</desc>
+</wpt>
+<wpt lat="42.432621000" lon="-71.106532000">
+ <ele>13.411200</ele>
+ <name>6979</name>
+ <cmt>6979</cmt>
+ <desc>6979</desc>
+</wpt>
+<wpt lat="42.431033000" lon="-71.107883000">
+ <ele>34.012085</ele>
+ <name>6997</name>
+ <cmt>6997</cmt>
+ <desc>6997</desc>
+</wpt>
+<wpt lat="42.465687000" lon="-71.107360000">
+ <ele>87.782400</ele>
+ <name>BEAR HILL</name>
+ <cmt>BEAR HILL TOWER</cmt>
+ <desc>BEAR HILL TOWER</desc>
+</wpt>
+<wpt lat="42.430950000" lon="-71.107628000">
+ <ele>23.469600</ele>
+ <name>BELLEVUE</name>
+ <cmt>BELLEVUE</cmt>
+ <desc>BELLEVUE</desc>
+</wpt>
+<wpt lat="42.438666000" lon="-71.114079000">
+ <ele>43.384766</ele>
+ <name>6016</name>
+ <cmt>Bike Loop Connector</cmt>
+ <desc>Bike Loop Connector</desc>
+</wpt>
+<wpt lat="42.456469000" lon="-71.124651000">
+ <ele>89.916000</ele>
+ <name>5236BRIDGE</name>
+ <cmt>Bridge</cmt>
+ <desc>Bridge</desc>
+</wpt>
+<wpt lat="42.465759000" lon="-71.119815000">
+ <ele>55.473600</ele>
+ <name>5376BRIDGE</name>
+ <cmt>Bridge</cmt>
+ <desc>Bridge</desc>
+</wpt>
+<wpt lat="42.442993000" lon="-71.105878000">
+ <ele>52.730400</ele>
+ <name>6181CROSS</name>
+ <cmt>Crossing</cmt>
+ <desc>Crossing</desc>
+</wpt>
+<wpt lat="42.435472000" lon="-71.109664000">
+ <ele>45.110400</ele>
+ <name>6042CROSS</name>
+ <cmt>Crossing</cmt>
+ <desc>Crossing</desc>
+</wpt>
+<wpt lat="42.458516000" lon="-71.103646000">
+ <name>DARKHOLLPO</name>
+ <cmt>Dark Hollow Pond</cmt>
+ <desc>Dark Hollow Pond</desc>
+</wpt>
+<wpt lat="42.443109000" lon="-71.112675000">
+ <ele>56.083200</ele>
+ <name>6121DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.449866000" lon="-71.119298000">
+ <ele>117.043200</ele>
+ <name>5179DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.459629000" lon="-71.116524000">
+ <ele>69.494400</ele>
+ <name>5299DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.465485000" lon="-71.119148000">
+ <ele>56.997600</ele>
+ <name>5376DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.462776000" lon="-71.109986000">
+ <ele>46.939200</ele>
+ <name>6353DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.446793000" lon="-71.108784000">
+ <ele>61.264800</ele>
+ <name>6155DEAD</name>
+ <cmt>Dead End</cmt>
+ <desc>Dead End</desc>
+</wpt>
+<wpt lat="42.451204000" lon="-71.126602000">
+ <ele>110.947200</ele>
+ <name>GATE14</name>
+ <cmt>Gate 14</cmt>
+ <desc>Gate 14</desc>
+</wpt>
+<wpt lat="42.458499000" lon="-71.122078000">
+ <ele>77.724000</ele>
+ <name>GATE16</name>
+ <cmt>Gate 16</cmt>
+ <desc>Gate 16</desc>
+</wpt>
+<wpt lat="42.459376000" lon="-71.119238000">
+ <ele>65.836800</ele>
+ <name>GATE17</name>
+ <cmt>Gate 17</cmt>
+ <desc>Gate 17</desc>
+</wpt>
+<wpt lat="42.466353000" lon="-71.119240000">
+ <ele>57.302400</ele>
+ <name>GATE19</name>
+ <cmt>Gate 19</cmt>
+ <desc>Gate 19</desc>
+</wpt>
+<wpt lat="42.468655000" lon="-71.107697000">
+ <ele>49.377600</ele>
+ <name>GATE21</name>
+ <cmt>Gate 21</cmt>
+ <desc>Gate 21</desc>
+</wpt>
+<wpt lat="42.456718000" lon="-71.102973000">
+ <ele>81.076800</ele>
+ <name>GATE24</name>
+ <cmt>Gate 24</cmt>
+ <desc>Gate 24</desc>
+</wpt>
+<wpt lat="42.430847000" lon="-71.107690000">
+ <ele>21.515015</ele>
+ <name>GATE5</name>
+ <cmt>Gate 5</cmt>
+ <desc>Gate 5</desc>
+</wpt>
+<wpt lat="42.431240000" lon="-71.109236000">
+ <ele>26.561890</ele>
+ <name>GATE6</name>
+ <cmt>Gate 6</cmt>
+ <desc>Gate 6</desc>
+</wpt>
+<wpt lat="42.439502000" lon="-71.106556000">
+ <ele>32.004000</ele>
+ <name>6077LOGS</name>
+ <cmt>Log Crossing</cmt>
+ <desc>Log Crossing</desc>
+</wpt>
+<wpt lat="42.449765000" lon="-71.122320000">
+ <ele>119.809082</ele>
+ <name>5148NANEPA</name>
+ <cmt>Nanepashemet Road Crossing</cmt>
+ <desc>Nanepashemet Road Crossing</desc>
+</wpt>
+<wpt lat="42.457388000" lon="-71.119845000">
+ <ele>73.761600</ele>
+ <name>5267OBSTAC</name>
+ <cmt>Obstacle</cmt>
+ <desc>Obstacle</desc>
+</wpt>
+<wpt lat="42.434980000" lon="-71.109942000">
+ <ele>45.307495</ele>
+ <name>PANTHRCAVE</name>
+ <cmt>Panther Cave</cmt>
+ <desc>Panther Cave</desc>
+</wpt>
+<wpt lat="42.453256000" lon="-71.121211000">
+ <ele>77.992066</ele>
+ <name>5252PURPLE</name>
+ <cmt>Purple Rock Hill</cmt>
+ <desc>Purple Rock Hill</desc>
+</wpt>
+<wpt lat="42.457734000" lon="-71.117481000">
+ <ele>67.970400</ele>
+ <name>5287WATER</name>
+ <cmt>Reservoir</cmt>
+ <desc>Reservoir</desc>
+</wpt>
+<wpt lat="42.459278000" lon="-71.124574000">
+ <ele>81.076800</ele>
+ <name>5239ROAD</name>
+ <cmt>Road</cmt>
+ <desc>Road</desc>
+</wpt>
+<wpt lat="42.458782000" lon="-71.118991000">
+ <ele>67.360800</ele>
+ <name>5278ROAD</name>
+ <cmt>Road</cmt>
+ <desc>Road</desc>
+</wpt>
+<wpt lat="42.439993000" lon="-71.120925000">
+ <ele>53.949600</ele>
+ <name>5058ROAD</name>
+ <cmt>ROAD CROSSING</cmt>
+ <desc>ROAD CROSSING</desc>
+</wpt>
+<wpt lat="42.453415000" lon="-71.106782000">
+ <ele>69.799200</ele>
+ <name>SHEEPFOLD</name>
+ <cmt>Sheepfold Parking Lot</cmt>
+ <desc>Sheepfold Parking Lot</desc>
+</wpt>
+<wpt lat="42.455956000" lon="-71.107483000">
+ <ele>64.008000</ele>
+ <name>SOAPBOX</name>
+ <cmt>Soap Box Derby Track</cmt>
+ <desc>Soap Box Derby Track</desc>
+</wpt>
+<wpt lat="42.465913000" lon="-71.119328000">
+ <ele>64.533692</ele>
+ <name>5376STREAM</name>
+ <cmt>Stream Crossing</cmt>
+ <desc>Stream Crossing</desc>
+</wpt>
+<wpt lat="42.445359000" lon="-71.122845000">
+ <ele>61.649902</ele>
+ <name>5144SUMMIT</name>
+ <cmt>Summit</cmt>
+ <desc>Summit</desc>
+</wpt>
+<wpt lat="42.441727000" lon="-71.121676000">
+ <ele>67.360800</ele>
+ <name>5150TANK</name>
+ <cmt>WATER TANK</cmt>
+ <desc>WATER TANK</desc>
+</wpt>
+<trk>
+<trkseg>
+<trkpt lat="30.062183000" lon="-91.610350000">
+ <ele>1.000000</ele>
+</trkpt>
+<trkpt lat="30.062783000" lon="-91.610567000">
+</trkpt>
+<trkpt lat="30.062700000" lon="-91.608267000">
+</trkpt>
+<trkpt lat="30.062333000" lon="-91.607383000">
+</trkpt>
+<trkpt lat="30.061533000" lon="-91.605283000">
+</trkpt>
+<trkpt lat="30.059783000" lon="-91.599400000">
+</trkpt>
+<trkpt lat="30.057800000" lon="-91.596683000">
+</trkpt>
+<trkpt lat="30.055383000" lon="-91.594900000">
+</trkpt>
+<trkpt lat="30.053883000" lon="-91.592617000">
+</trkpt>
+<trkpt lat="30.049733000" lon="-91.589750000">
+</trkpt>
+<trkpt lat="30.049017000" lon="-91.589883000">
+</trkpt>
+<trkpt lat="30.048800000" lon="-91.592933000">
+</trkpt>
+<trkpt lat="30.046233000" lon="-91.596450000">
+</trkpt>
+<trkpt lat="30.045517000" lon="-91.598717000">
+</trkpt>
+<trkpt lat="30.047300000" lon="-91.600267000">
+</trkpt>
+<trkpt lat="30.047000000" lon="-91.599633000">
+ <ele>2.000000</ele>
+</trkpt>
+<trkpt lat="30.046433000" lon="-91.599467000">
+</trkpt>
+<trkpt lat="30.046200000" lon="-91.598950000">
+ <ele>1.000000</ele>
+</trkpt>
+<trkpt lat="30.046367000" lon="-91.597733000">
+</trkpt>
+<trkpt lat="30.046350000" lon="-91.597167000">
+</trkpt>
+<trkpt lat="30.046783000" lon="-91.596333000">
+</trkpt>
+<trkpt lat="30.047450000" lon="-91.595200000">
+</trkpt>
+<trkpt lat="30.047800000" lon="-91.594767000">
+ <ele>2.000000</ele>
+</trkpt>
+<trkpt lat="30.048250000" lon="-91.594083000">
+ <ele>1.000000</ele>
+</trkpt>
+<trkpt lat="30.048683000" lon="-91.593800000">
+ <ele>1.000000</ele>
+</trkpt>
+<trkpt lat="30.049350000" lon="-91.593850000">
+</trkpt>
+<trkpt lat="30.050317000" lon="-91.593983000">
+ <ele>2.000000</ele>
+</trkpt>
+<trkpt lat="30.050783000" lon="-91.594117000">
+</trkpt>
+<trkpt lat="30.051233000" lon="-91.594367000">
+</trkpt>
+<trkpt lat="30.051800000" lon="-91.594367000">
+</trkpt>
+<trkpt lat="30.052217000" lon="-91.594667000">
+</trkpt>
+<trkpt lat="30.053017000" lon="-91.594683000">
+</trkpt>
+<trkpt lat="30.054867000" lon="-91.595200000">
+ <ele>6.000000</ele>
+</trkpt>
+<trkpt lat="30.053733000" lon="-91.594933000">
+ <ele>2.000000</ele>
+</trkpt>
+<trkpt lat="30.053183000" lon="-91.594783000">
+</trkpt>
+<trkpt lat="30.052633000" lon="-91.594833000">
+</trkpt>
+<trkpt lat="30.052450000" lon="-91.595433000">
+</trkpt>
+<trkpt lat="30.052483000" lon="-91.595967000">
+</trkpt>
+<trkpt lat="30.052650000" lon="-91.596783000">
+ <ele>1.000000</ele>
+</trkpt>
+<trkpt lat="30.053133000" lon="-91.597850000">
+</trkpt>
+<trkpt lat="30.053617000" lon="-91.597967000">
+</trkpt>
+<trkpt lat="30.053967000" lon="-91.597767000">
+ <ele>6.000000</ele>
+</trkpt>
+<trkpt lat="30.053617000" lon="-91.598083000">
+</trkpt>
+<trkpt lat="30.053200000" lon="-91.597917000">
+</trkpt>
+<trkpt lat="30.052817000" lon="-91.597517000">
+</trkpt>
+<trkpt lat="30.052567000" lon="-91.596933000">
+</trkpt>
+<trkpt lat="30.052333000" lon="-91.596433000">
+</trkpt>
+<trkpt lat="30.052250000" lon="-91.595683000">
+</trkpt>
+<trkpt lat="30.052217000" lon="-91.595017000">
+</trkpt>
+<trkpt lat="30.051883000" lon="-91.594700000">
+</trkpt>
+<trkpt lat="30.051050000" lon="-91.594400000">
+</trkpt>
+<trkpt lat="30.050567000" lon="-91.594233000">
+</trkpt>
+<trkpt lat="30.050183000" lon="-91.594100000">
+</trkpt>
+<trkpt lat="30.049100000" lon="-91.593717000">
+</trkpt>
+<trkpt lat="30.048450000" lon="-91.594250000">
+</trkpt>
+<trkpt lat="30.048083000" lon="-91.594750000">
+</trkpt>
+<trkpt lat="30.047500000" lon="-91.595450000">
+ <ele>7.000000</ele>
+</trkpt>
+<trkpt lat="30.047067000" lon="-91.596000000">
+</trkpt>
+<trkpt lat="30.046633000" lon="-91.596600000">
+</trkpt>
+<trkpt lat="30.046400000" lon="-91.597650000">
+</trkpt>
+<trkpt lat="30.046233000" lon="-91.598467000">
+</trkpt>
+<trkpt lat="30.046317000" lon="-91.598967000">
+</trkpt>
+<trkpt lat="30.046783000" lon="-91.599283000">
+</trkpt>
+<trkpt lat="30.047133000" lon="-91.599667000">
+</trkpt>
+</trkseg>
+</trk>
+</gpx>